package com.yimi.appstore.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.zip.GZIPInputStream;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.ConnectionPoolTimeoutException;
import org.apache.http.conn.HttpHostConnectException;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import android.util.Log;

import com.yimi.appstore.YimiApplication;

/**
 * httpclient 帮助类
 * 
 * @author Administrator
 * 
 */
public class HttpClientUtil {
	private static final String TAG = "HttpUtil";

	private static Header[] headers = null;

	private static HttpClientUtil mHttpUtil = null;

	/** 请求字符集编码 */
	private static final String CHARSET = HTTP.UTF_8;

	/** 从连接池中取连接的超时时间 */
	private static final int TIME_OUT_CONN_MANAGER = 80000;

	/** 网络连接超时 */
	private static final int TIME_OUT_HTTP_CONN = 80000;

	/** http请求超时 */
	private static final int TIME_OUT_HTTP_SOC = 100000;

	private static HttpClient mHttpClient;

	private HttpClientUtil() {
		getHttpClient();
		AboutMobileInfoTools amit = AboutMobileInfoTools.getInstance(YimiApplication.context);
		HashMap<String, String> headmap = (amit != null ? amit.getDeviceInfoMap() : null);
		if (headmap != null) {
			HttpHead head = new HttpHead();
			for (Entry entry : headmap.entrySet()) {
				head.addHeader(String.valueOf(entry.getKey()), String.valueOf(entry.getValue()).replaceAll("_", "-"));
			}
			head.addHeader("Accept-Encoding", "gzip");
		}
	}

	public static synchronized HttpClientUtil getInstance() {
		if (mHttpUtil == null) {
			mHttpUtil = new HttpClientUtil();
		}
		return mHttpUtil;
	}

	public synchronized HttpClient getHttpClient() {
		if (null == mHttpClient) {
			HttpParams params = new BasicHttpParams();
			// 设置一些基本参数
			HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
			HttpProtocolParams.setContentCharset(params, CHARSET);
			HttpProtocolParams.setUseExpectContinue(params, true);
			HttpProtocolParams.setUserAgent(params, System.getProperty("http.agent"));
			Log.i(TAG, "HttpProtocolParams.getUserAgent:" + HttpProtocolParams.getUserAgent(params));
			// 超时设置
			/* 从连接池中取连接的超时时间 */
			ConnManagerParams.setTimeout(params, TIME_OUT_CONN_MANAGER);
			/* 连接超时 */
			HttpConnectionParams.setConnectionTimeout(params, TIME_OUT_HTTP_CONN);
			/* 请求超时 */
			HttpConnectionParams.setSoTimeout(params, TIME_OUT_HTTP_SOC);

			// 设置我们的HttpClient支持HTTP和HTTPS两种模式
			SchemeRegistry schReg = new SchemeRegistry();
			schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
			schReg.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));

			// 使用线程安全的连接管理来创建HttpClient
			ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schReg);
			mHttpClient = new DefaultHttpClient(conMgr, params);
		}
		return mHttpClient;
	}

	public String httpGet(String url, HashMap<String, String> params, HashMap<String, String> out_error_holder) {
		long startTime = System.currentTimeMillis();
		String result = null;
		if (params != null) {
			for (Entry<String, String> entry : params.entrySet()) {
				url = url.replace("{" + entry.getKey() + "}", entry.getValue());
			}
		}
		Log.i(TAG, "request= " + url);
		HttpGet request = new HttpGet(url);
		if (headers != null) {
			request.setHeaders(headers);
		}
		request.addHeader("Accept-Encoding", "gzip");
		try {
			HttpResponse response = mHttpClient.execute(request);
			if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
				HttpEntity httpEntity = response.getEntity();
				if (httpEntity.getContentEncoding() != null && httpEntity.getContentEncoding().getValue() != null
						&& httpEntity.getContentEncoding().getValue().contains("gzip")) {
					InputStream is = httpEntity.getContent();
					is = new GZIPInputStream(is);
					BufferedReader br = new BufferedReader(new InputStreamReader(is));
					String line = null;
					StringBuffer sb = new StringBuffer();
					while ((line = br.readLine()) != null) {
						sb.append(line);
					}
					result = sb.toString();
				} else {
					result = EntityUtils.toString(response.getEntity(), CHARSET);
				}
				long endTime = System.currentTimeMillis();
				Log.d(TAG, "----------请求时间-------------" + (endTime - startTime) + "毫秒");
				Log.d(TAG, "result= " + result);
				return result;
			} else {
				Log.d(TAG, "result null");
				return null;
			}
		} catch (ClientProtocolException e) {
			Log.e(TAG, e.toString());

			setErrorException(out_error_holder);
		} catch (ConnectionPoolTimeoutException e) {
			Log.e(TAG, e.toString());

			setErrorException(out_error_holder);
		} catch (ConnectTimeoutException e) {
			Log.e(TAG, e.toString());

			setErrorException(out_error_holder);
		} catch (HttpHostConnectException e) {
			Log.e(TAG, e.toString());

			setErrorException(out_error_holder);
		} catch (IOException e) {
			Log.e(TAG, e.toString());

			setErrorException(out_error_holder);
		} catch (Exception e) {
			Log.e(TAG, e.toString());

			setErrorException(out_error_holder);
		}
		Log.d(TAG, "result null");
		return null;
	}

	public String httpPost(String url, List<NameValuePair> params, HashMap<String, String> out_error_holder) {
		Log.i(TAG, "request post= " + url);

		HttpPost httpRequest = new HttpPost(url);
		if (headers != null) {
			httpRequest.setHeaders(headers);
		}

		try {
			// 设置字符集
			HttpEntity httpentity = new UrlEncodedFormEntity(params, CHARSET);
			// 请求httpRequest
			httpRequest.setEntity(httpentity);
			// 取得默认的HttpClient
			HttpClient httpclient = new DefaultHttpClient();
			// 取得HttpResponse
			HttpResponse httpResponse = httpclient.execute(httpRequest);
			Log.e(TAG, "************" + httpResponse.getStatusLine().getStatusCode());
			if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
				String result = EntityUtils.toString(httpResponse.getEntity(), CHARSET);
				Log.d(TAG, "result post= " + result);
				return result;
			}
		} catch (ClientProtocolException e) {
			Log.e(TAG, e.toString());

			setErrorException(out_error_holder);
		} catch (ConnectionPoolTimeoutException e) {
			Log.e(TAG, e.toString());

			setErrorException(out_error_holder);
		} catch (ConnectTimeoutException e) {
			Log.e(TAG, e.toString());

			setErrorException(out_error_holder);
		} catch (HttpHostConnectException e) {
			Log.e(TAG, e.toString());

			setErrorException(out_error_holder);
		} catch (IOException e) {
			Log.e(TAG, e.toString());

			setErrorException(out_error_holder);
		} catch (Exception e) {
			Log.e(TAG, e.toString());

			setErrorException(out_error_holder);
		}
		Log.d(TAG, "result null");
		return null;
	}

	private void setErrorException(HashMap<String, String> out_error_holder) {
		if (out_error_holder != null) {
			out_error_holder.put("errorcode", "-13");
			out_error_holder.put("errormessage", "网络连接异常！");
		}
	}
}
